
<!DOCTYPE html
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml">
   <head>
      <meta charset="utf-8"></meta>
      <meta name="viewport" content="width=device-width, initial-scale=1.0"></meta>
      <title>15.3.&nbsp;Merge Nodes - Chapter&nbsp;15.&nbsp;Graph Refactoring</title>
      <link rel="stylesheet" type="text/css" href="../../docbook.css"></link>
      <link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"></link>
      <link rel="stylesheet" type="text/css" href="//cdn.datatables.net/1.10.13/css/jquery.dataTables.min.css"></link>
      <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.1.0/css/font-awesome.min.css"></link>
      <link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Open+Sans:400,300,400italic,600,300italic"></link>
      <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/codemirror.min.css"></link>
      <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/theme/neo.min.css"></link>
      <link rel="stylesheet" type="text/css" href="../../css/chunked-base.css"></link>
      <link rel="stylesheet" type="text/css" href="../../css/extra.css"></link><script src="//code.jquery.com/jquery-1.12.4.js" type="text/javascript"></script><script src="//cdn.datatables.net/1.10.13/js/jquery.dataTables.min.js" type="text/javascript"></script><script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" type="text/javascript"></script><script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/codemirror.min.js" type="text/javascript"></script><script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/addon/runmode/runmode.min.js" type="text/javascript"></script><script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/mode/cypher/cypher.min.js" type="text/javascript"></script><script src="../../javascript/datatable.js" type="text/javascript"></script><script src="../../javascript/colorize.js" type="text/javascript"></script><script src="../../javascript/tabs-for-chunked.js" type="text/javascript"></script><script src="../../javascript/mp-nav.js" type="text/javascript"></script><script src="../../javascript/versionswitcher.js" type="text/javascript"></script><script src="../../javascript/version.js" type="text/javascript"></script><script src="//s3-eu-west-1.amazonaws.com/alpha.neohq.net/docs/new-manual/assets/search.js" type="text/javascript"></script><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"></meta>
      <link rel="prev" href="../clone-subgraph/" title="15.2.&nbsp;Clone subgraph"></link>
      <link rel="next" href="../redirect-relationship/" title="15.4.&nbsp;Redirect relationships"></link>
      <link rel="shortcut icon" href="https://neo4j.com/wp-content/themes/neo4jweb/favicon.ico"></link><script>
        $(document).ready(function() {
          CodeMirror.colorize();
          tabTheSource($('body'));
          var $header = $('header').first();
          $header.prepend(
            $('<a href="" id="logo"><img src="https://neo4j.com/wp-content/themes/neo4jweb/assets/images/neo4j-logo-2015.png" alt="Neo4j Logo"></img></a>')
          );
          var $sidebar = $('<div id="sidebar-wrapper"></div>');
          $.get('toc.html', function (d){
            $(d).appendTo($sidebar);
            highlightToc();
            highlightLibraryHeader();
          });
          $sidebar.insertAfter($('header').first());
        });
        </script></head>
   <body>
      <header>
         <div class="searchbox">
            <form id="search-form" class="search" name="search-form" role="search"><input id="search-form-input" name="q" title="search" type="search" lang="en" placeholder="Search Neo4j docs..." aria-label="Search Neo4j documentation" max-length="128" required="required"></input><input id="search-form-button" type="submit" value="Search"></input></form>
         </div>
         <ul class="documentation-library">
            <li><a href="https://neo4j.com/docs/operations-manual/current">Operations Manual</a></li>
            <li><a href="https://neo4j.com/docs/developer-manual/current/">Developer Manual</a></li>
            <li><a href="https://neo4j.com/docs/ogm-manual/current/">OGM Manual</a></li>
            <li><a href="https://neo4j.com/docs/graph-algorithms/current/">Graph Algorithms</a></li>
            <li><a href="https://neo4j-contrib.github.io/neo4j-apoc-procedures/3.5/">APOC</a></li>
            <li><a href="https://neo4j.com/docs/java-reference/current/">Java Reference</a></li>
         </ul>
         <nav id="header-nav"><span class="nav-previous"><a accesskey="p" href="../clone-subgraph/"><span class="fa fa-long-arrow-left" aria-hidden="true"></span>Clone subgraph</a></span><span class="nav-current">
               <p class="nav-title hidden">15.3.&nbsp;Merge Nodes</p></span><span class="nav-next"><a accesskey="n" href="../redirect-relationship/">Redirect relationships<span class="fa fa-long-arrow-right" aria-hidden="true"></span></a></span></nav>
      </header>
      <div id="search-results" class="hidden"></div>
      <section class="section" id="merge-nodes">
         <div class="titlepage">
            <div>
               <div>
                  <h2 class="title" style="clear: both"><a class="anchor" href="#merge-nodes"></a>15.3.&nbsp;Merge Nodes
                  </h2>
               </div>
            </div>
         </div>
         <p>You can merge a list of nodes onto the first one in the list.</p>
         <p>All relationships are merged onto that node too.
            You can specify the merge behavior for properties globally and/or individually.
         </p><pre class="programlisting highlight"><code data-lang="cypher">---
MATCH (p:Person)
WITH p ORDER BY p.created DESC // newest one first
WITH p.email, collect(p) as nodes
CALL apoc.refactor.mergeNodes(nodes, {properties: {name:'discard', age:'overwrite', kids:'combine', `addr.*`, 'overwrite',`.*`: 'discard'}}) YIELD node
RETURN node
---</code></pre><p>This config option also works for <code class="literal">apoc.refactor.mergeRelationships([rels],{config})</code>.
         </p>
         <div class="informaltable">
            <div class="table" id="d0e18599">
               <table class="informaltable" border="1">
                  <colgroup>
                     <col class="col_1"></col>
                     <col class="col_2"></col>
                  </colgroup>
                  <thead>
                     <tr>
                        <th style="text-align: left; vertical-align: top; ">type</th>
                        <th style="text-align: left; vertical-align: top; ">operations</th>
                     </tr>
                  </thead>
                  <tbody>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>discard</p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>the first nodes' property will remain if already set, otherwise the first property in list will be written</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>overwrite / override</p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>&nbsp;last property in list wins</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>combine</p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>if there is only one property in list, it will be set / kept as single property otherwise create an array, tries to coerce
                              values
                           </p>
                        </td>
                     </tr>
                  </tbody>
               </table>
            </div>
         </div>
         <p>For mergeNodes you can Merge relationships with same type and direction, you can spacify this with property mergeRels.
            Relationships properties are managed with the same nodes' method, if properties parameter isn&#8217;t set relationships properties
            are combined.
         </p>
         <p><span class="formalpara-title">example1 - Relationships with same start and end nodes.&nbsp;</span>First of all we have to create nodes and relationships
         </p><pre class="programlisting highlight"><code data-lang="cypher">Create (n1:Person {name:'Tom'}),
(n2:Person {name:'John'}),
(n3:Company {name:'Company1'}),
(n5:Car {brand:'Ferrari'}),
(n6:Animal:Cat {name:'Derby'}),
(n7:City {name:'London'}),
(n1)-[:WORKS_FOR{since:2015}]-&gt;(n3),
(n2)-[:WORKS_FOR{since:2018}]-&gt;(n3),
(n3)-[:HAS_HQ{since:2004}]-&gt;(n7),
(n1)-[:DRIVE{since:2017}]-&gt;(n5),
(n2)-[:HAS{since:2013}]-&gt;(n6)
return *;</code></pre><div class="informalfigure">
            <div class="mediaobject"><img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.4/docs/images/apoc.refactor.mergeNodes.createDataSetFirstExample.png" alt="apoc.refactor.mergeNodes.createDataSetFirstExample"></img></div>
         </div>
         <p>Next step is calling the apoc to merge nodes :Person</p><pre class="programlisting highlight"><code data-lang="cypher">MATCH (a1:Person{name:'John'}), (a2:Person {name:'Tom'})
WITH head(collect([a1,a2])) as nodes
CALL apoc.refactor.mergeNodes(nodes,{properties:"combine", mergeRels:true}) yield node
MATCH (n)-[r:WORKS_FOR]-&gt;(c) return *</code></pre><p>and the result is:</p>
         <div class="informalfigure">
            <div class="mediaobject"><img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.4/docs/images/apoc.refactor.mergeNodes.resultFirstExample.png" alt="apoc.refactor.mergeNodes.resultFirstExample"></img></div>
         </div>
         <p>In this case we have relationships with same start and end nodes so relationships are merged into one and properties are combined.</p>
         <p>Relationships with different start or end nodes</p><pre class="programlisting highlight"><code data-lang="cypher">Create (n1:Person {name:'Tom'}),
(n2:Person {name:'John'}),
(n3:Company {name:'Company1'}),
(n4:Company {name:'Company2'}),
(n5:Car {brand:'Ferrari'}),
(n6:Animal:Cat {name:'Derby'}),
(n7:City {name:'London'}),
(n8:City {name:'Liverpool'}),
(n1)-[:WORKS_FOR{since:2015}]-&gt;(n3),
(n2)-[:WORKS_FOR{since:2018}]-&gt;(n4),
(n3)-[:HAS_HQ{since:2004}]-&gt;(n7),
(n4)-[:HAS_HQ{since:2007}]-&gt;(n8),
(n1)-[:DRIVE{since:2017}]-&gt;(n5),
(n2)-[:HAS{since:2013}]-&gt;(n6)
return *;</code></pre><div class="informalfigure">
            <div class="mediaobject"><img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.4/docs/images/apoc.refactor.mergeNodes.createDataSetSecondExample.png" alt="apoc.refactor.mergeNodes.createDataSetSecondExample"></img></div>
         </div>
         <p>Next step is calling the apoc to merge nodes :Person</p><pre class="programlisting highlight"><code data-lang="cypher">MATCH (a1:Person{name:'John'}), (a2:Person {name:'Tom'})
WITH head(collect([a1,a2])) as nodes
CALL apoc.refactor.mergeNodes(nodes,{properties:"combine", mergeRels:true}) yield node
MATCH (n)-[r:WORKS_FOR]-&gt;(c) return n.name,r.since,c.name;</code></pre><p>and the result is:</p>
         <div class="informalfigure">
            <div class="mediaobject"><img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.4/docs/images/apoc.refactor.mergeNodes.resultSecondExample.png" alt="apoc.refactor.mergeNodes.resultSecondExample"></img></div>
         </div>
         <div class="informalfigure">
            <div class="mediaobject"><img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.4/docs/images/apoc.refactor.mergeNodes.resultSecondExampleData.png" alt="apoc.refactor.mergeNodes.resultSecondExampleData"></img></div>
         </div>
         <p>In this case we have relationships with different end nodes so all relationships are maintained and properties are combined
            into all relationships.
         </p><pre class="programlisting highlight"><code data-lang="cypher">MATCH (p:Person)
WITH p ORDER BY p.created DESC // newest one first
WITH p.email, collect(p) as nodes
CALL apoc.refactor.mergeNodes(nodes, {properties:'combine', mergeRels: true}) YIELD node
RETURN node</code></pre></section>
      <footer><script type="text/javascript">
          (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
          m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
          })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
          //Allow Linker
          ga('create', 'UA-1192232-34','auto', {'allowLinker': true});
          ga('send', 'pageview');
          // Load the plugin.
          ga('require', 'linker');
          // Define which domains to autoLink.
          ga('linker:autoLink', ['neo4j.org','neo4j.com','neotechnology.com','graphdatabases.com','graphconnect.com']);
        </script><script type="text/javascript">
          document.write(unescape("%3Cscript src='//munchkin.marketo.net/munchkin.js' type='text/javascript'%3E%3C/script%3E"));
        </script><script>Munchkin.init('773-GON-065');</script></footer>
   </body>
</html>